<template>
  <div>
    <el-form ref="form" label-width="80px" :model="spu">
      <el-form-item label="SPU名称">
        <el-input placeholder="SPU名称" v-model="spu.spuName"></el-input>
      </el-form-item>
      <el-form-item label="品牌">
        <el-select placeholder="请选择品牌" v-model="spu.tmId">
          <el-option
            :label="tm.tmName"
            :value="tm.id"
            v-for="(tm, index) in tradeMarkList"
            :key="tm.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input
          type="textarea"
          rows="4"
          placeholder="SPU描述"
          v-model="spu.description"
        ></el-input>
      </el-form-item>
      <el-form-item label="SPU图片">
        <!-- 上传图片：
          action图片上传的地址
          list-type: 文件列表的类型
          on-preview:图片预览的时候会出发
          on-remove:当删除图片的时候会出发
          file-list：照片墙需要展示的数据【数组：数组里面的元素务必要有name、url属性】
          on-preview：图片预览功能
          on-remove:删除图片的时候会触发
        -->
        <el-upload
          action="/dev-api/admin/product/fileUpload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handlerSuccess"
          :file-list="spuImageList"
        >
          <i class="el-icon-plus"></i>
        </el-upload>
		<!-- 预览大图 -->
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性">
        <!-- value 用作存储收集数据 -->
        <el-select :placeholder="`还有${unSelectSaleAttr.length}未选择`" v-model="attrIdAndAttrName">
          <el-option :label="unselect.name" :value="`${unselect.id}:${unselect.name}`" v-for="(unselect,index) in unSelectSaleAttr" :key="unselect.id"></el-option>
        </el-select>
        <!-- :diabled 动态绑定disabled 禁用与否 为真时禁用  -->
        <el-button type="primary" icon="el-icon-plus" :disabled="!attrIdAndAttrName" @click="addSaleAttr">添加销售属性</el-button>
        <!-- 当前SPU自己销售属性  label标题数据 prop 内容数据-->
        <el-table style="width: 100%" border :data="spu.spuSaleAttrList">
          <el-table-column prop="prop" label="序号" width="80" type="index" align="center">
          </el-table-column>
          <el-table-column prop="saleAttrName" label="属性名" width="width">
          </el-table-column>
          <el-table-column prop="prop" label="属性值名称列表" width="width">
            <template slot-scope="{ row, $index }">
              <!-- row销售属性 -->
              <!-- el-tag:用户展示已有属性值列表的数据的 -->
              <el-tag :key="tag.id" 
				v-for="(tag, index) in row.spuSaleAttrValueList"
                closable :disable-transitions="false" 
				@close="row.spuSaleAttrValueList.splice(index, 1)">
                {{ tag.saleAttrValueName }}
              </el-tag>
              <!-- 底下的解构可以当中咱们当年的span与input切换 -->
              <!--  @keyup.enter.native="handleInputConfirm"  -->
			  <!-- 此处inputVisible不能写在data中 el-tag有多个 控制input和 button切换隐藏 -->
              <el-input
                class="input-new-tag"
                v-if="row.inputVisible"
                v-model="row.inputValue"
                ref="saveTagInput"
                size="small"
                @blur="handleInputConfirm(row)">
              </el-input>
              <!-- @click="showInput" -->
              <el-button
                v-else 
				class="button-new-tag"
                size="small" @click="addSaleAttrValue(row)">
                添加
              </el-button>
            </template>
          </el-table-column>
          <el-table-column prop="prop" label="操作" width="width">
            <template slot-scope="{ row, $index }">
            <el-button
                type="danger"
                icon="el-icon-delete"
                size="mini"
                @click="spu.spuSaleAttrList.splice($index, 1)">
			</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="addOrUpdateSpu">保存</el-button>
        <el-button @click="cancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  name: "SpuForm",
  data() {
    return {
      dialogImageUrl: "",
      dialogVisible: false,
      spu: {
        //三级分类的id
        category3Id: 0,
        //描述
        description: "",
        //spu名称
        spuName: "",
        //平台的id
        tmId: "",
        //收集SPU图片的信息
        spuImageList: [
          // {
          //   id: 0,
          //   imgName: "string",
          //   imgUrl: "string",
          //   spuId: 0,
          // },
        ],
        //平台属性与属性值收集
        spuSaleAttrList: [
          // {
          //   baseSaleAttrId: 0,
          //   id: 0,
          //   saleAttrName: "string",
          //   spuId: 0,
          //   spuSaleAttrValueList: [
          //     {
          //       baseSaleAttrId: 0,
          //       id: 0,
          //       isChecked: "string",
          //       saleAttrName: "string",
          //       saleAttrValueName: "string",
          //       spuId: 0,
          //     },
          //   ],
          // },
        ],
      }, //存储SPU值属性 初始值为空对象 后期可以作收集数据
      tradeMarkList: [], //存储品牌信息
      spuImageList: [], //存储SPU图片数据
      saleAttrList: [], //销售属性的数据（项目全部的销售属性）
      attrIdAndAttrName:''//收集未选择的销售属性ID
    };
  },
  methods: {
    //照片墙删除某一个图片的时候会触发
    handleRemove(file, fileList) {
      //file参数:代表的是删除的那个张图片
      //fileList:照片墙删除某一张图片以后，剩余的其他的图片
      // console.log(file, fileList,22222);
      //收集照片墙图片的数据
      //对于已有的图片【照片钱中显示的图片：有name、url字段的】，因为照片墙显示数据务必要有这两个属性
      //对于服务器而言，不需要name、url字段，将来对于有的图片的数据在提交给服务器的时候，需要处理的
	  // 更新spuImageList
      this.spuImageList = fileList;
    },
    //照片墙图片预览的回调
    handlePictureCardPreview(file) {
      //将图片地址赋值给这个属性
	  // console.log(file.url)
      this.dialogImageUrl = file.url;
      //对话框显示
      this.dialogVisible = true;
    },
    // 初始化SPUform数据
    async initSpuData(spu) {
      // 修改SPU时 需要向服务器发送请求 将服务器返回数据对象 赋值给SPU对象
      // 添加SPU时 未向服务器发请求 数据收集到SPU 但此处SPU初始值为空对象并不方便收集 不符合需求 需要根据文档设置对象
      // console.log('发请求',spu)
      // 获取SPU信息数据
      let spuResult = await this.$API.spu.reqSpu(spu.id);
      // console.log(spuResult)
      if (spuResult.code == 200) {
        this.spu = spuResult.data;
      }
      // 获取品牌信息
      let tradeMarkResult = await this.$API.spu.reqTradeMarkList();
      // console.log(tradeMarkResult)
      if (tradeMarkResult.code == 200) {
        this.tradeMarkList = tradeMarkResult.data;
      }
      // 获取SPU图片数据
      let spuImageResult = await this.$API.spu.reqSpuImageList(spu.id);
      // console.log(spuImageResult)
      if (spuImageResult.code == 200) {
        let listArr = spuImageResult.data;
        // 照片墙显示图片数组需要有name和url属性才会显示 故此处需先处理返回数据
        listArr.forEach((item) => {
          item.name = item.imgName;
          item.url = item.imgUrl;
        });
        // 把整理好的数据赋值给spuImageList
        this.spuImageList = listArr;
      }
      // 获取平台销售属性
      let saleResult = await this.$API.spu.reqBaseSaleAttrList();
      // console.log(saleResult)
      if (saleResult.code == 200) {
        this.saleAttrList = saleResult.data;
      }
    },
		// 照片墙图片上传成功回调
		handlerSuccess(response,file,fileList){
			// file 上传成功的图片 fileList上传成功后的所有图片信息
			// console.log(response)  respone服务器返回信息
			this.spuImageList = fileList
		},
		// 添加新的销售属性
	addSaleAttr(){
		// 把收集到的销售属性数据进行分割
		const [baseSaleAttrId,saleAttrName] = this.attrIdAndAttrName.split(':')
		// 整理数据
		let newSaleAttr = {baseSaleAttrId,saleAttrName,spuSaleAttrValueList:[]}
		// 向SPU对象spuSaleAttrList添加新的属性
		this.spu.spuSaleAttrList.push(newSaleAttr)
		// 清空数据
		this.attrIdAndAttrName = ''
	},
	// 点击添加按钮回调
	addSaleAttrValue(row){
		// 点击添加销售属性值按钮时 button展示为input
		// console.log(row)
		// row.inputVisible = true 此处添加不是响应式 Vue无法检测到新添加的属性值
		// $set添加的新属性 Vue能检测到
		// 挂载在销售属性身上的响应式数据 控制button与input切换
		this.$set(row,'inputVisible',true)
		// 通过响应式数据inputValue字段设置为空 挂载到row销售属性上 收集新增销售属性值
		this.$set(row,'inputValue','')
	},
	// el-input失去焦点事件
	handleInputConfirm(row){
		// 修改inputViible为return false;
		row.inputVisible = false
		// 解构销售属性当中收集数据
		// console.log(row)
		const {baseSaleAttrId,inputValue} = row
		// 1 新增销售属性值不能为空
		if(inputValue.trim() == ''){
			this.$message('属性值不能为空')
			return
		}
		// 2 新增属性值不能重复
		let result = row.spuSaleAttrValueList.every(item=>item.saleAttrValueName!=inputValue)
		// console.log(result)
		if(!result){
			this.$message('属性值不能重复')
			return
		}
		// 整理数据
		let newSaleAttrValue = {baseSaleAttrId,saleAttrValueName:inputValue}
		// 新增属性值数据
		row.spuSaleAttrValueList.push(newSaleAttrValue)
	},
	//保存按钮回调
	async addOrUpdateSpu(){
		// 整理参数
		// 整理图片照片墙数据 服务器需要携带imgName和imgUrl map返回一个新数组
		this.spu.spuImageList = this.spuImageList.map(item=>{
			return {
				imageName:item.name,
				imageUrl:(item.response&&item.response.data) || item.url
			}
		})
		// 发请求
		let result = await this.$API.spu.reqAddOrUpdateSpu(this.spu)
		// console.log(result)
		if(result.code == 200){
			this.$mesaage({
				type:'success',
				message:'保存成功'
			})
		// 通知父组件回到场景 0
		this.$emit('changeScene',{scene:0,flag:this.spu.id?'修改':'添加'})
		}
		Object.assign(this._data,this.$options.data())
	},
	// 点击添加SPU 子组件发请求 回调函数
	async addSpuData(category3Id){
		// 添加ＳＰＵ时收集三级分类ID 
		this.spu.category3Id = category3Id
		// 获取品牌信息
		let tradeMarkResult = await this.$API.spu.reqTradeMarkList();
		// console.log(tradeMarkResult)
		if (tradeMarkResult.code == 200) {
		  this.tradeMarkList = tradeMarkResult.data;
		}
		// 获取平台销售属性
		let saleResult = await this.$API.spu.reqBaseSaleAttrList();
		// console.log(saleResult)
		if (saleResult.code == 200) {
		  this.saleAttrList = saleResult.data;
		}
	},
	// 取消按钮回调
	cancel(){
		this.$emit('changeScene', {scene:0,flag:''})
		// 清理数据
		// Object.assign合并对象
		// this._data 当前挂载的响应式数据
		// this.$options.data()最开始配置对象
		Object.assign(this._data,this.$options.data())
	}
  },
  computed:{
    // 筛选还未选择的销售属性
    unSelectSaleAttr(){
      // 整个平台属性 saleAttrList
      // 当前SPU属于自己的SPU属性SPU.spuSaleAttrList
      // filter 从已有数组当中筛选出符合条件的元素 并返回新的数组
      let result = this.saleAttrList.filter(item=>{
        // console.log(item)
        // every数组方法 返回布尔值真或假 此处类双重for循环
        return this.spu.spuSaleAttrList.every(item1=>{
          return item.name!= item1.saleAttrName
        })
      })
      // 计算属性需要有返回值
      return result
    }
  }
};
</script>

<style scoped>
.el-tag + .el-tag {
  margin-left: 10px;
}
.button-new-tag {
  margin-left: 10px;
  margin-top: 8px;
  height: 32px;
  line-height: 30px;
  padding-top: 0;
  padding-bottom: 0;
}
.input-new-tag {
  width: 90px;
  margin-left: 10px;
  vertical-align: bottom;
}
</style>

